package gl.java.javascript;


import com.sun.istack.internal.Nullable;
import gl.java.game.Timer;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import lombok.extern.slf4j.Slf4j;

import javax.script.ScriptEngine;

@Slf4j
public class JavaScriptWindow {

    private final Timer timer;

    public JavaScriptWindow() {
        timer = new Timer();
    }


    public long setTimeout(@Nullable ScriptObjectMirror runnable, long millisecond) {
        long l = timer.setTimeout(() -> {
            try {
                runnable.call(runnable);
            } catch (Exception e) {
                log.error(e.getMessage(),e);
            }
        }, millisecond);
        log.debug("setTimeout.ID:{},timeout:{}ms", l, millisecond);
        return l;
    }


    public long setInterval(@Nullable ScriptObjectMirror runnable, long millisecond) {
        long l = timer.setInterval(() -> {
            try {
                runnable.call(runnable);
            } catch (Exception e) {
                log.error(e.getMessage(),e);
            }
        }, millisecond);
        log.debug("setInterval.ID:{} interval:{}ms", l, millisecond);
        return l;
    }

    public void clearInterval(@Nullable long id) {
        timer.clearInterval(id);
    }

    public void clearTimeout(@Nullable long id) {
        timer.clearTimeout(id);
    }

    public void attach(ScriptEngine engine) {
        try {
            //inject console.log && error
            engine.put("NativeLog", log);
            engine.put("String", new String());
            engine.eval("var console = NativeLog;var String = Java.type('java.lang.String');\n" +
                    "console.info('[DEFINE LOG],{},{}',1,2);\n"+
                    "var log = {};"+
                    "log.i = console.info;"+
                    "log.d = console.debug;"+
                    "log.w = console.warn;"+
                    "log.e = console.error;"

            );

            //inject window.setTimeout && window.clearInterval
            engine.put("window", this);
            engine.eval("var setTimeout= function (func,timeoutInMS) {\n" +
                    "    return window.setTimeout(func,timeoutInMS);\n" +
                    "};\n" +
                    "var setInterval= function (func,timeoutInMS) {\n" +
                    "    return window.setInterval(func,timeoutInMS);\n" +
                    "};\n" +
                    "var clearInterval = function (ID) {\n" +
                    "    window.clearInterval(ID);\n" +
                    "};\n" +
                    "var clearTimeout = function (ID) {\n" +
                    "    window.clearTimeout(ID);\n" +
                    "};");

        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
        }
    }

    public void detach() {
        timer.clearAll();
    }
}
